Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Cholesky factorisation #202

Merged
merged 8 commits into from
Aug 4, 2022
Merged

Add Cholesky factorisation #202

merged 8 commits into from
Aug 4, 2022

Conversation

AlexRobson
Copy link
Member

@AlexRobson AlexRobson commented Aug 3, 2022

Presently Cholesky isn't supported with NamedDims.

Adding this was made fairly easy with the NamedFactorisation. It throws a dimensionamismatch if the axes are not named the same. Also includes the suggested linting changes from JuliaFormatter for some lines that were not part of this MR.

src/functions_linearalgebra.jl Outdated Show resolved Hide resolved
src/functions_linearalgebra.jl Outdated Show resolved Hide resolved
src/functions_linearalgebra.jl Outdated Show resolved Hide resolved
src/functions_linearalgebra.jl Outdated Show resolved Hide resolved
src/functions_linearalgebra.jl Outdated Show resolved Hide resolved
test/functions_linearalgebra.jl Outdated Show resolved Hide resolved
test/functions_linearalgebra.jl Outdated Show resolved Hide resolved
test/functions_linearalgebra.jl Outdated Show resolved Hide resolved
test/functions_linearalgebra.jl Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Aug 3, 2022

Codecov Report

Merging #202 (585c946) into master (f803d70) will increase coverage by 0.07%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #202      +/-   ##
==========================================
+ Coverage   94.71%   94.79%   +0.07%     
==========================================
  Files          14       14              
  Lines         662      672      +10     
==========================================
+ Hits          627      637      +10     
  Misses         35       35              
Impacted Files Coverage Δ
src/functions_linearalgebra.jl 96.34% <100.00%> (+0.50%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

n1, n2 = L
@assert n1 == n2 # Must be identical given square pdmat?
if d === :L
return NamedDimsArray{(n1, n2)}(inner)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For cholesky, I assume that both the lower triangular and upper triangular being square matricies would correspond to the same axis.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would be my assumption as well. That being said, there's nothing stopping someone from constructing a factorization type with a square matrix, but having different names. Should probably replace the @assert with a DimensionMismatch error though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could probably also rewrite this block as:

return d in (:L, :U) ? NamedDimsArray{(n1, n2)}(inner) : inner

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realised actually we don't want the dimcheck at the point of getproperty, but at the point of constructing the NamedFactoriztion. I've added a new constructor for this

@@ -26,6 +26,7 @@ Base.propertynames(named::NamedFactorization; kwargs...) = propertynames(parent(
Base.iterate(named::NamedFactorization{L, T, <:LU}) where {L, T} = (named.L, Val(:U))
Base.iterate(named::NamedFactorization{L, T, <:LQ}) where {L, T} = (named.L, Val(:Q))
Base.iterate(named::NamedFactorization{L, T, <:SVD}) where {L, T} = (named.U, Val(:S))
Base.iterate(named::NamedFactorization{L, T, <:Cholesky}) where {L, T} = (named.L, Val(:U))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC this correctly, this should return:

r = rand(4,4); Σ = r' * r
_l, _u = cholesky(Σ)
cholesky(Σ).L == _l
cholesky(Σ).U == _u

Compare with lu::

_l, _u = lu(Σ)
lu(Σ).L == _l # True
lu(Σ).U == _u # True

Copy link
Member Author

@AlexRobson AlexRobson Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is working on julia 1 (1.6 and 1.7) but failing on 1.3 and 1.5

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's fine. Though we should probably make this a minor release if you'd prefer to just pin the Julia version to 1.6 or higher.

test/functions_linearalgebra.jl Show resolved Hide resolved
test/functions_linearalgebra.jl Show resolved Hide resolved
@rofinn rofinn self-requested a review August 3, 2022 16:31
Copy link
Member

@rofinn rofinn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems mostly fine apart from cleaning up the @assert and bumping the release for Julia >=1.6.

@@ -26,6 +26,7 @@ Base.propertynames(named::NamedFactorization; kwargs...) = propertynames(parent(
Base.iterate(named::NamedFactorization{L, T, <:LU}) where {L, T} = (named.L, Val(:U))
Base.iterate(named::NamedFactorization{L, T, <:LQ}) where {L, T} = (named.L, Val(:Q))
Base.iterate(named::NamedFactorization{L, T, <:SVD}) where {L, T} = (named.U, Val(:S))
Base.iterate(named::NamedFactorization{L, T, <:Cholesky}) where {L, T} = (named.L, Val(:U))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's fine. Though we should probably make this a minor release if you'd prefer to just pin the Julia version to 1.6 or higher.

n1, n2 = L
@assert n1 == n2 # Must be identical given square pdmat?
if d === :L
return NamedDimsArray{(n1, n2)}(inner)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would be my assumption as well. That being said, there's nothing stopping someone from constructing a factorization type with a square matrix, but having different names. Should probably replace the @assert with a DimensionMismatch error though.

n1, n2 = L
@assert n1 == n2 # Must be identical given square pdmat?
if d === :L
return NamedDimsArray{(n1, n2)}(inner)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could probably also rewrite this block as:

return d in (:L, :U) ? NamedDimsArray{(n1, n2)}(inner) : inner

test/functions_linearalgebra.jl Show resolved Hide resolved
src/functions_linearalgebra.jl Outdated Show resolved Hide resolved
src/functions_linearalgebra.jl Outdated Show resolved Hide resolved
src/functions_linearalgebra.jl Show resolved Hide resolved
test/functions_linearalgebra.jl Outdated Show resolved Hide resolved
Alex Robson and others added 2 commits August 4, 2022 10:05
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@test dimnames(x.L) == (:foo, :foo)
@test dimnames(x.U) == (:foo, :foo)

@test_throws DimensionMismatch cholesky(nda_mismatch)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now throw an error if there is a dim-mismatch.

@@ -30,11 +29,6 @@ jobs:
arch: x86
- os: windows-latest
arch: x86
include:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop julia < 1.6 in CI

@@ -1,7 +1,7 @@
name = "NamedDims"
uuid = "356022a1-0364-5f58-8944-0da4b18d706f"
authors = ["Invenia Technical Computing Corporation"]
version = "0.2.49"
version = "0.3.0"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

major bump due to constrainting julia to 1.6 and above

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the future, this should be a patch bump to be non-breaking (since the package is pre-1.0) unless one intends to support backports: https://github.com/SciML/ColPrac/pull/20/files

@AlexRobson AlexRobson requested a review from rofinn August 4, 2022 09:42
@AlexRobson AlexRobson changed the title [WIP] Add Cholesky factorisation Add Cholesky factorisation Aug 4, 2022
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
n1, n2 = L
return d in (:L, :U) ? NamedDimsArray{(n1, n2)}(inner) : inner
end
function NamedFactorization{L}(fact::Cholesky{T}) where {L,T}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define a new constructor to handle the dimension mismatch

Copy link
Member

@rofinn rofinn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looks fine to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants